<template>
    <div class="box">
        <!-- 面包屑导航区 -->
        <t-breadcrumb :maxItemWidth="'150'">
            <t-breadcrumbItem :to="{ path: '/dashboard' }">首页</t-breadcrumbItem>
            <t-breadcrumbItem>商品管理</t-breadcrumbItem>
            <t-breadcrumbItem :maxWidth="'160'">参数列表</t-breadcrumbItem>
        </t-breadcrumb>

        <!-- 卡片视图区域 -->
        <t-card>
            <!-- 警告区域 -->
            <t-alert message="注意：只允许第三级分类设置相关参数！" theme="warning" />

            <!-- 选择商品分类区域 -->
            <t-row class="cat_opt">
                <t-col>
                    <t-form>
                        <t-form-item label="选择商品分类">
                            <!-- options用来指定数据源 -->
                            <!-- keys用来指定配置对象 -->
                            <t-cascader v-model="selectedCateKeys" value-type="full" :options="cateList" :keys="cateProps"
                                trigger="hover" @change="handleChange" clearable />
                        </t-form-item>
                    </t-form>
                </t-col>
            </t-row>

            <!-- tab 页签区域 -->
            <t-tabs v-model="activeName" @change="handleTabClick">
                <!-- 添加动态参数的面板 -->
                <t-tab-panel value="many" label="动态参数">
                    <!-- 添加参数的按钮 -->
                    <t-button :disabled="isBtnDisabled" @click="addDialogVisible = true">添加参数</t-button>
                    <!-- 动态参数表格 -->
                    <t-table rowKey="index" :data="manyTabData" :columns="manyColumns" :expanded-row-keys="expandedRowKeys"
                        :expandIcon="expandIcon" expandOnRowClick @expand-change="rehandleExpandChange" stripe bordered
                        hover resizable>
                        <!-- 插槽方式 自定义单元格， colKey 的值默认为插槽名称  -->
                        <template #operate="{ row }">
                            <t-space>
                                <!-- 编辑按钮 -->
                                <t-button theme="primary" size="small" @click.stop="showEditDialog(row.attr_id)"><i
                                        class="iconfont icon-bianji"></i>编辑</t-button>
                                <!-- 删除按钮 -->
                                <t-button theme="danger" size="small" @click.stop="removeParamsById(row.attr_id)"><i
                                        class="iconfont icon-shanchu"></i>删除</t-button>
                            </t-space>
                        </template>

                        <!-- !! 也可以使用具名插槽 `expandedRow` 自定义展开行内容 !! -->
                        <template #expandedRow="{ row }">
                            <!-- 循环渲染Tag标签 -->
                            <t-tag v-for="(item, index) in row.attr_vals" :key="index" theme="primary" variant="light" closable
                                @close="handleClose(index, row)">{{ item }}</t-tag>

                            <!-- 添加的按钮 -->
                            <t-tag v-if="!row.inputVisible" theme="primary" variant="light" @click="handleClickAdd(row)">
                                <add-icon />
                                添加标签
                            </t-tag>
                            <!-- 输入的文本框 -->
                            <t-input v-else ref="input" v-model="row.inputValue" size="small" style="width: 94px"
                                @blur="handleInputEnter(row)" @enter="handleInputEnter(row)" />
                        </template>
                    </t-table>
                </t-tab-panel>
                <!-- 添加静态属性的面板 -->
                <t-tab-panel value="only" label="静态属性">
                    <!-- 添加属性的按钮 -->
                    <t-button :disabled="isBtnDisabled" @click="addDialogVisible = true">添加属性</t-button>
                    <!-- 静态属性表格 -->
                    <t-table rowKey="index" :data="onlyTabData" :columns="onlyColumns" :expanded-row-keys="expandedRowKeys"
                        :expandIcon="expandIcon" expandOnRowClick @expand-change="rehandleExpandChange" stripe bordered
                        hover resizable>
                        <!-- 插槽方式 自定义单元格， colKey 的值默认为插槽名称  -->
                        <template #operate="{ row }">
                            <t-space>
                                <!-- 编辑按钮 -->
                                <t-button theme="primary" size="small" @click.stop="showEditDialog(row.attr_id)"><i
                                        class="iconfont icon-bianji"></i>编辑</t-button>
                                <!-- 删除按钮 -->
                                <t-button theme="danger" size="small" @click.stop="removeParamsById(row.attr_id)"><i
                                        class="iconfont icon-shanchu"></i>删除</t-button>
                            </t-space>
                        </template>

                        <!-- !! 也可以使用具名插槽 `expandedRow` 自定义展开行内容 !! -->
                        <template #expandedRow="{ row }">
                            <!-- 循环渲染Tag标签 -->
                            <t-tag v-for="(item, index) in row.attr_vals" :key="index" theme="primary" variant="light"
                                closable @close="handleClose(index, row)">{{ item }}</t-tag>

                            <!-- 添加的按钮 -->
                            <t-tag v-if="!row.inputVisible" theme="primary" variant="light" @click="handleClickAdd(row)">
                                <add-icon />
                                添加标签
                            </t-tag>
                            <!-- 输入的文本框 -->
                            <t-input v-else ref="input" v-model="row.inputValue" size="small" style="width: 94px"
                                @blur="handleInputEnter(row)" @enter="handleInputEnter(row)" />
                        </template>
                    </t-table>
                </t-tab-panel>
            </t-tabs>
        </t-card>

        <!-- 添加参数的对话框 -->
        <t-dialog :header="this.activeName === 'many' ? '动态参数' : '静态属性'" :footer="false" :visible.sync="addDialogVisible"
            @close="addDialogClosed">
            <t-form :data="addForm" ref="addFormRef" :rules="addFormRules" @submit="addParams">
                <!-- 主体区域 -->
                <t-form-item :label="this.activeName === 'many' ? '动态参数' : '静态属性'" name="attr_name">
                    <t-input v-model="addForm.attr_name"
                        :placeholder="this.activeName === 'many' ? '请输入动态参数' : '请输入静态属性'" />
                </t-form-item>
                <!-- 按钮区域 -->
                <template>
                    <div style="float: right">
                        <t-space>
                            <t-button theme="default" @click="addDialogClosed">取消</t-button>
                            <t-button theme="primary" type="submit">确定</t-button>
                        </t-space>
                    </div>
                </template>
            </t-form>
        </t-dialog>

        <!-- 修改参数的对话框 -->
        <t-dialog :header="this.activeName === 'many' ? '动态参数' : '静态属性'" :footer="false" :visible.sync="editDialogVisible"
            @close="editDialogClosed">
            <t-form :data="editForm" ref="editFormRef" :rules="editFormRules" @submit="editParams">
                <!-- 主体区域 -->
                <t-form-item :label="this.activeName === 'many' ? '动态参数' : '静态属性'" name="attr_name">
                    <t-input v-model="editForm.attr_name"
                        :placeholder="this.activeName === 'many' ? '请输入动态参数' : '请输入静态属性'" />
                </t-form-item>
                <!-- 按钮区域 -->
                <template>
                    <div style="float: right">
                        <t-space>
                            <t-button theme="default" @click="editDialogClosed">取消</t-button>
                            <t-button theme="primary" type="submit">确定</t-button>
                        </t-space>
                    </div>
                </template>
            </t-form>
        </t-dialog>
    </div>
</template>

<script>
import {
    ChevronRightCircleIcon,
    ChevronRightIcon,
    AddIcon,
} from 'tdesign-icons-vue'

import Vue from 'vue'

export default {

    components: {
        AddIcon,
    },

    created() {
        // 获取所有的商品分类列表
        this.getCateList()
    },

    data() {
        return {

            // 商品分类列表
            cateList: [],
            // 级联选择框的配置对象
            cateProps: {
                value: 'cat_id',
                label: 'cat_name',
                children: 'children',
            },
            // 级联选择框双向绑定到的数组
            selectedCateKeys: [],
            // 被激活的页签的名称
            activeName: 'many',
            // 动态参数的数据
            manyTabData: [],
            manyColumns: [
                { colKey: 'index', title: '#', width: '20' },
                { colKey: 'attr_name', title: '参数名称', width: '200' },
                { colKey: 'operate', title: '操作', width: '165' },
            ],
            // 静态属性的数据
            onlyTabData: [],
            onlyColumns: [
                { colKey: 'index', title: '#', width: '20' },
                { colKey: 'attr_name', title: '属性名称', width: '200' },
                { colKey: 'operate', title: '操作', width: '165' },
            ],

            // 控制添加对话框的显示与隐藏
            addDialogVisible: false,
            // 控制添加对话框的显示与隐藏
            editDialogVisible: false,

            // 添加参数的表单数据对象
            addForm: {
                attr_name: '',
            },
            // 添加表单的验证规则对象
            addFormRules: {
                attr_name: [
                    {
                        required: true,
                        message: '请输入参数名称',
                        type: 'error',
                        trigger: 'blur',
                    },
                    { whitespace: true, message: '参数名称不能为空' },
                    {
                        min: 2,
                        message: '至少需要两个字符，一个中文等于两个字符',
                        type: 'warning',
                        trigger: 'blur',
                    },
                    {
                        max: 10,
                        message: '参数名称字符长度超出',
                        type: 'warning',
                        trigger: 'blur',
                    },
                ],
            },
            // 编辑参数的表单数据对象
            editForm: {
                attr_name: '',
            },
            // 编辑表单的验证规则对象
            editFormRules: {
                attr_name: [
                    {
                        required: true,
                        message: '请输入名称',
                        type: 'error',
                        trigger: 'blur',
                    },
                    { whitespace: true, message: '名称不能为空' },
                    {
                        min: 2,
                        message: '至少需要两个字符，一个中文等于两个字符',
                        type: 'warning',
                        trigger: 'blur',
                    },
                    {
                        max: 10,
                        message: '名称字符长度超出',
                        type: 'warning',
                        trigger: 'blur',
                    },
                ],
            },

            expandControl: 'true',
            // 用于自定义展开图标，值为 true 显示默认图标，值为 false 不显示图标，值为函数则表示完全自定义图标。
            expandIcon: true,
            // 有哪些 data.id 在 expandedRowKeys 中，就显示这些 id 对应的行
            expandedRowKeys: [102],

            // 控制按钮与文本框的切换显示
            inputVisible: false,
            inputValue: '',

        }
    },

    methods: {
        // 获取商品分类列表
        async getCateList() {
            const { data: res } = await this.$http.get('categories')

            if (res.meta.status !== 200) {
                this.$message.error('获取商品分类失败！')
            } else {
                this.cateList = res.data
            }
        },
        // 级联选择框选中项变化会触发这个函数
        handleChange() {
            this.getParamsData()

        },
        // Tab 页签点击事件的处理函数
        handleTabClick() {
            this.getParamsData()
        },

        // 获取参数的列表数据
        async getParamsData() {

            // 只允许选择三级分类
            if (this.selectedCateKeys.length !== 3) {
                this.selectedCateKeys = []
                this.manyTabData = []
                this.onlyTabData = []
                return
            }

            // 根据所选分类的Id,和当前所处的面板，获取对应的参数
            const { data: res } = await this.$http.get(`categories/${this.cateId}/attributes`, { params: { sel: this.activeName } })

            if (res.meta.status !== 200) {
                this.$message.error('获取参数列表失败')
            } else {

                // 追加 index 字段 处理 attr_vals 转为数组
                res.data.forEach((item, index) => {
                    item.index = index + 1;
                    item.attr_vals = item.attr_vals ? item.attr_vals.split(' ') : []
                    // 控制文本框的显示与隐藏
                    item.inputVisible = false
                    // 文本框中输入的值
                    item.inputValue = ''
                })

                // 根据 activeName 值动态赋值数据
                if (this.activeName === 'many') {
                    this.manyTabData = res.data
                } else {
                    this.onlyTabData = res.data
                }
            }
        },

        // 点击展开列
        rehandleExpandChange(value, params) {
            this.expandedRowKeys = value;
        },

        // 监听添加对话框的关闭事件
        addDialogClosed() {
            this.addDialogVisible = false
            this.$refs.addFormRef.reset()
        },

        // 点击按钮，添加参数
        async addParams({ validateResult, firstError }) {
            if (validateResult === true) {
                const { data: res } = await this.$http.post(`categories/${this.cateId}/attributes`, {
                    attr_name: this.addForm.attr_name,
                    attr_sel: this.activeName,
                })
                if (res.meta.status !== 201) {
                    this.$message.error('添加参数失败！')
                } else {
                    this.$message.success('添加参数成功！')
                    // 置空添加表单数据
                    this.addForm.attr_name = ''
                    // 隐藏添加参数的对话框
                    this.addDialogVisible = false
                    // 重新获取参数列表数据
                    this.getParamsData()
                }
            } else {
                this.$message.warning(firstError);
            }
        },

        // 点击编辑，展示修改的对话框
        async showEditDialog(attr_id) {

            // 查询当前参数的信息
            const { data: res } = await this.$http.get(`categories/${this.cateId}/attributes/${attr_id}`, {
                params: {
                    attr_sel: this.activeName,
                }
            })

            if (res.meta.status !== 200) {
                this.$message.error('获取参数信息失败！')
            } else {
                this.editForm = res.data
                this.editDialogVisible = true
            }

        },

        // 监听编辑对话框的关闭事件
        editDialogClosed() {
            this.editDialogVisible = false
            this.$refs.editFormRef.reset()
        },

        // 点击确定，修改参数
        async editParams({ validateResult, firstError }) {
            if (validateResult === true) {
                const { data: res } = await this.$http.put(`categories/${this.cateId}/attributes/${this.editForm.attr_id}`, {
                    attr_name: this.editForm.attr_name,
                    attr_sel: this.activeName,
                })

                if (res.meta.status !== 200) {
                    this.$message.error('修改参数失败！')
                } else {
                    this.$message.success('修改参数成功！')
                    // 隐藏修改参数的对话框
                    this.editDialogVisible = false
                    // 重新获取参数列表数据
                    this.getParamsData()
                }
            } else {
                this.$message.warning(firstError);
            }
        },

        // 根据Id删除对应的参数项
        removeParamsById(attr_id) {
            // 弹窗询问用户是否删除数据
            const confirmDia = this.$dialog.confirm({
                header: '提示',
                body: '次操作将永久删除该参数，是否继续？',
                confirmBtn: '确定',
                cancelBtn: '取消',
                onConfirm: async ({ e }) => {
                    // console.log('confirm button has been clicked!');
                    // console.log('e: ', e);
                    const { data: res } = await this.$http.delete(`categories/${this.cateId}/attributes/${attr_id}/`)
                    if (res.meta.status !== 200) {
                        this.$message.error('删除参数失败！')
                    } else {
                        this.getParamsData()
                        this.$message.success('删除参数成功！')
                        // 请求成功后，销毁弹框
                        confirmDia.destroy();
                    }
                },
                onClose: ({ e, trigger }) => {
                    this.$message.info('已取消删除')
                    // console.log('e: ', e);
                    // console.log('trigger: ', trigger);
                    confirmDia.hide();
                },
            })
        },
        // 文本框失去焦点，或按下了 Enter 都会触发 
        async handleInputEnter(row) {
            if (row.inputValue.trim().length === 0) {
                row.inputValue = ''
                row.inputVisible = false
                return
            }

            // 如果没有 return，则证明用户输入了内容，需要做后续处理
            row.attr_vals.push(row.inputValue.trim())
            row.inputValue = ''
            row.inputVisible = false

            // 需要发起请求，保存这次操作的结果
            this.saveAttrVals(row)

        },

        // 将对 attr_vals 对操作保存到数据库
        async saveAttrVals(row) {

            const { data: res } = await this.$http.put(`categories/${this.cateId}/attributes/${row.attr_id}`, {
                attr_name: row.attr_name,
                attr_sel: row.attr_sel,
                attr_vals: row.attr_vals.join(' ')
            })

            if (res.meta.status !== 200) {
                this.$message.error('修改参数项失败！')
            } else {
                this.$message.success('修改参数项成功！')
            }
        },

        // 点击添加按钮，展示输入文本框 
        handleClickAdd(row) {
            row.inputVisible = true

            // $nextTick 方法的作用：就是当页面上元素被重新渲染之后，才会指定回调函数中的代码
            Vue.nextTick(() => {
                this.$refs.input.focus();
            });
        },

        // 删除对应的参数可选项
        handleClose(index, row) {
            row.attr_vals.splice(index, 1)
            this.saveAttrVals(row)
        },

    },

    computed: {
        // 如果按钮被禁用，则返回 true 否则返回 false
        isBtnDisabled() {
            if (this.selectedCateKeys.length !== 3) {
                return true
            } else {
                return false
            }
        },
        // 当前选中的三级分类的Id
        cateId() {
            if (this.selectedCateKeys.length === 3) {
                return this.selectedCateKeys[2]
            } else {
                return null
            }
        },
    },

    watch: {
        expandControl(val) {
            if (val === 'true') {
                // expandIcon 默认为 true，表示显示默认展开图标
                this.expandIcon = true;
            } else if (val === 'false') {
                // expandIcon 值为 false，则表示隐藏全部展开图标
                this.expandIcon = false;
            } else if (val === 'custom') {
                // 完全自由控制表格的每一行是否显示展开图标，以及显示什么内容
                this.expandIcon = (h, { index }) => {
                    // 第一行不显示展开图标
                    if (index === 0) return false;
                    // 第三行，使用自定义展开图标
                    if (index === 3) return <ChevronRightIcon />;
                    // 其他行，使用表格同款展开图标
                    return <ChevronRightCircleIcon />;
                };
            }
        },
    },

}
</script>

<style lang="less" scoped>
.box {
    padding: 15px;

    .t-alert {
        background-color: #FFF1E9;

        /deep/ .t-alert__description {
            color: #f2a738;
        }
    }

    .cat_opt {
        margin: 15px 0;
    }

    .t-tab-panel {
        padding-top: 15px;
    }

    .t-tag {
        margin: 5px;
    }

}
</style>